CUBE CONNECT Edition Help

Querying Shortest Paths

The CubeDatabase class provides the shortestPath() method, that takes the network name and the query definition arguments.

The query definition is defined by using the ShortestPathQuery method. This serves as a container set for the various parameters that may be used within a shortest path query. These arguments are the following:

  • The initial node (called “origin”). This can be a centroid or a network node.
  • The final node (called “destination”). This can be a centroid or a network node.
  • The cost expression that is minimized when calculating the shortest path, which uses Lua expressions.
  • A Boolean that is defining if to include centroid connectors or not in the calculation of the shortest path.
  • A LinkEntryVector, defined based on LinkEntry, to exclude links from the path building process.
An example of a single distance-based path between two centroid nodes is defined below, printing the sequence of links and their cost.
db = cp.CubeDatabase(source_db, False)

node_start = 24  
node_end = 19  

# Defining the cost measure for shortest-path calculation 
cost_lua_expression = "cost(link.distance)"

# Excluding links vector
exclude_vector = cp.LinkEntryVector()
x = cp.LinkEntry(600, 601)
exclude_vector.append(x)

query_definition = cp.ShortestPathQuery(node_start, node_end, cost_lua_expression, False, exclude_vector)
path = db.shortestPath(network_name, query_definition)

for path_link in path.links: 
    print(path_link.a, path_link.b, path_link.cost)
It is possible to use a list of node pairs and use the ShortestPathQueryVector() to append multiple ShortestPathQuery statements for queries definition. The shortestPaths(network_name, queries_definition) method will generate the shortest path for all the pairs of nodes. An example is provided below.
db = cp.CubeDatabase(source_db, False)

start_end_nodes_list = [(690, 685), (685, 448), (448, 742), (742, 758)]
cost_expression = "cost(link.distance)"  # (Lua expression)

# Excluding links vector (none in this example
exclude_vector = cp.LinkEntryVector()

queries_definition = cp.ShortestPathQueryVector()

for node_start, node_end in start_end_nodes_list:
    queries_definition.append(cp.ShortestPathQuery(node_start, node_end, cost_expression, False, exclude_vector))

paths = db.shortestPaths(network_name, queries_definition)

path_index = 0
for path in paths:
    node_start = start_end_nodes_list[path_index][0]
    node_end = start_end_nodes_list[path_index][1]
    if len(path.links) == 0:
        print(f"No path found from {node_start} to {node_end} under these conditions")
    else:
        print(f"The path from {node_start} to {node_end} is formed of a sequence of", len(path.links), "links")
        sum_cost = 0
        for path_link in path.links:
            sum_cost += path_link.cost
            print(f"{path_link.a:<10}",
                  f"{path_link.b:<10}",
                  f"{path_link.cost:<10,.3f}",
                  f"{sum_cost:<10,.3f}")
    path_index += 1